package sparrowGui.component
{
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Point;
	import flash.utils.getTimer;
	
	import sparrowGui.SparrowGUI;
	import sparrowGui.utils.EventDispatcherEx;
	
	/**
	 * 基本提示窗,本控件只用于跟椐目标延时显示提示窗
	 * 鼠标经过对象提示,弹出菜单提示继承于此控件
	 * 
	 * 如要延时X秒显示某对象到按钮A的位置:
	 *	
	 * 	var sb:SimpleButton = new SimpleButton();
	 *	var tip:BaseTip = new BaseTip(stage);
	 *  tip.show(sb,"aabb");
	 *   
	 * @author Pelephone
	 */
	public class BaseTip extends EventDispatcherEx
	{
		public static const TIPS_UPDATA:String = "TIPS_UPDATA";		//组件内容更新
		
		public static const TIPS_POSI_AUTO:int = 0;	//0.提示框自动根据边距出现在鼠标上下左右,默认在右下
		public static const TIPS_POSI_AUTO_UP:int = 7;	//0.提示框自动根据边距出现在鼠标上下左右,默认在右下
		
		public static const TIPS_POSI_RD:int = 1;	//1.右下
		public static const TIPS_POSI_RU:int = 2;	//2.右上
		public static const TIPS_POSI_LU:int = 3;	//3.左上
		public static const TIPS_POSI_LD:int = 4;	//4.左下
		public static const TIPS_POSI_UM:int = 5;	//上居中
		public static const TIPS_POSI_DM:int = 6;	//下居中
		public static const TIPS_POSI_M_AUTO:int = 10;	//自动居中上下提示
		
		/**
		 * 本组件控制的皮肤
		 */
		protected var _skin:Sprite;
		/**
		 * 组件名
		 */
		private var _name:String;
		
		private var _showPos:int;
		private var _offSet:Number;
		private var _delay:int;
		
		/**
		 * 开始计时显示的时间点,仅用于缓存
		 */
		private var startTime:int;
		/**
		 * 显示提示窗的父级容器
		 */
		protected var showParent:DisplayObjectContainer;
		
		/**
		 * 构造基本提示窗工具
		 * @param parentSkin	必须填父级容器,不然弹出的提示不知道要置于哪层
		 * @param argSkin		被弹出的对象
		 */
		public function BaseTip(parentSkin:DisplayObjectContainer,argSkin:Sprite=null)
		{
			showParent = parentSkin;
			create(argSkin);
			super();
		}
		
		/**
		 * 通过皮肤激活此控件
		 * @param argSkin
		 */
		protected function create(argSkin:Sprite):void
		{
			argSkin = argSkin || new Sprite();
			_skin = argSkin;
			_name = _skin.name;
		}
		
		public function update(data:Object):void
		{
			dispatchEvent(new Event(TIPS_UPDATA));
		}
		
		/**
		 * 延迟后显示tarDisp对象在鼠标附近
		 * @param data 数据		
		 * @param tarDisp 要显示的显示对象
		 */
		public function show(data:Object=null,tarDisp:DisplayObject=null):void
		{
			update(data);
			startTime = getTimer();
			
			var localPt:Point = tarDisp.localToGlobal(new Point(0,0));
			var px:int = localPt.x;
			var py:int = localPt.y;
			var tarWidth:Number = tarDisp?tarDisp.width:0;
			var tarHeight:Number = tarDisp?tarDisp.height:0;
			setTipPos(px,py,tarWidth,tarHeight);
			
			if(!skin.hasEventListener(Event.ENTER_FRAME))
				skin.addEventListener(Event.ENTER_FRAME,onEnterEvt);
			
/*			showParent.stage.addEventListener(Event.MOUSE_LEAVE,onMouseLeave);
		}
		
		private function onMouseLeave(e:Event):void
		{
			clearUp();*/
		}
		
		protected function onEnterEvt(e:Event):void
		{
			if((getTimer()-startTime)<delay ||!this.showParent ) return;
			showParent.addChild(skin);
			skin.visible = true;
			skin.removeEventListener(Event.ENTER_FRAME,onEnterEvt);
			// 把这个打开再屏掉removeEventListener(Event.ENTER_FRAME,onEvt);便鼠标跟随的动
			//						setTipPosi(overTip);
		}
		
		/**
		 * 设计提示框相对目前对象的位置
		 * 屏幕的左上右下过界的判断
		 */
		protected function setTipPos(px:int,py:int,tarWidth:Number=0,tarHeight:Number=0):void
		{
			var spacing:int = offSet;
			
			var swidth:int = SparrowGUI.stageWidth;
			var sheight:int = SparrowGUI.stageHeight;
			
			// 复杂的坐标算法
			if(((showPos==TIPS_POSI_AUTO || showPos==TIPS_POSI_AUTO_UP)
				&& ((px + spacing + tarWidth + skin.width)>swidth))
				|| showPos==TIPS_POSI_LU || showPos==TIPS_POSI_LD)
				skin.x = (px - spacing - skin.width);
			else if(showPos==TIPS_POSI_UM || showPos==TIPS_POSI_DM || showPos==TIPS_POSI_M_AUTO)
				skin.x = px - skin.width/2 + tarWidth/2;
			else
				skin.x = (px + tarWidth + spacing);
			
			// y轴是跟据底部边距判断是否出界,出界就以底部参考调整位置,反之以tarObj为参考
			if(showPos==TIPS_POSI_AUTO || showPos==TIPS_POSI_DM || showPos==TIPS_POSI_AUTO_UP
				|| showPos==TIPS_POSI_UM || showPos==TIPS_POSI_RU || showPos==TIPS_POSI_LU)
			{
				if((py + spacing + tarHeight + skin.height)>sheight && showPos==TIPS_POSI_AUTO)
					skin.y = (sheight - spacing - skin.height);
				else if((py - spacing - tarHeight - skin.height)<0 && showPos==TIPS_POSI_AUTO_UP)
					skin.y = spacing;
				else if(showPos==TIPS_POSI_DM || showPos==TIPS_POSI_AUTO)
					skin.y = (py + spacing + tarHeight);
				else
					skin.y = (py - spacing - skin.height);
			}
			else
			{
				skin.y = (py + tarHeight + spacing);
			}
		}
		
		/**
		 * 显示到坐标
		 * @param posX
		 * @param posY
		 * @param data
		 */
		public function showByPos(posX:Number,posY:Number,data:Object=null):void
		{
			update(data);
			startTime = getTimer();
			
			setTipPos(posX,posY);
			
			if(!skin.hasEventListener(Event.ENTER_FRAME))
				skin.addEventListener(Event.ENTER_FRAME,onEnterEvt);
		}
		
		/**
		 * 移除提示对象
		 */
		public function clearUp():void
		{
//			showParent.stage.removeEventListener(Event.MOUSE_LEAVE,onMouseLeave);
			skin.removeEventListener(Event.ENTER_FRAME,onEnterEvt);
			if(skin.parent) showParent.removeChild(skin);
			skin.visible = false;
		}
		
		
		//////////////////////////////////
		// get/set
		//////////////////////////////////

		/**
		 * 显示的方位
		 */
		public function get showPos():int
		{
			return _showPos;
		}

		/**
		 * @private
		 */
		public function set showPos(value:int):void
		{
			_showPos = value;
		}

		/**
		 * 偏移
		 */
		public function get offSet():Number
		{
			return _offSet;
		}

		/**
		 * @private
		 */
		public function set offSet(value:Number):void
		{
			_offSet = value;
		}

		/**
		 * 延时毫秒数
		 */
		public function get delay():int
		{
			return _delay;
		}

		/**
		 * @private
		 */
		public function set delay(value:int):void
		{
			_delay = value;
		}
		
		public function get skin():Sprite
		{
			return _skin;
		}
	}
}